Nir Adar גירסה 1.00 עמוד 1

Σχετικά έγγραφα
עצי 2-3 תזכורת: בנים. דוגמאות: Chapter 19: B trees ( ) Chapter 15: Augmenting data structures ( )

משוואות רקורסיביות רקורסיה זו משוואה או אי שוויון אשר מתארת פונקציה בעזרת ערכי הפונקציה על ארגומנטים קטנים. למשל: יונתן יניב, דוד וייץ

פתרון תרגיל מרחבים וקטורים. x = s t ולכן. ur uur נסמן, ur uur לכן U הוא. ur uur. ur uur

מבני נתונים ואלגוריתמים תרגול #3 נושאים: תור קדימויות/ערימה, עצים

חורף תש''ע פתרון בחינה סופית מועד א'

Nir Adar

אסימפטוטיים תוכנית הקורס עצי AVL עצי 2-3 עצי דרגות סיבוכיות משוערכת מיון מיון שימושים: גרפים איסוף אשפה

ל הזכויות שמורות לדפנה וסטרייך

מבני נתונים ויעילות אלגוריתמים

פתרון תרגיל 8. מרחבים וקטורים פרישה, תלות \ אי-תלות לינארית, בסיס ומימד ... ( ) ( ) ( ) = L. uuruuruur. { v,v,v ( ) ( ) ( ) ( )

תורת הגרפים - סימונים

שדות תזכורת: פולינום ממעלה 2 או 3 מעל שדה הוא פריק אם ורק אם יש לו שורש בשדה. שקיימים 5 מספרים שלמים שונים , ראשוני. שעבורם

צעד ראשון להצטיינות מבוא: קבוצות מיוחדות של מספרים ממשיים

(2) מיונים השאלות. .0 left right n 1. void Sort(int A[], int left, int right) { int p;

תרגול מס' 6 פתרון מערכת משוואות ליניארית

תרגיל 13 משפטי רול ולגראנז הערות

2 יח"ל ) השלמה ל - 5 יח"ל) (50 נקודות) מעבר חוקי, ו-'שקר' אחרת.

= 2. + sin(240 ) = = 3 ( tan(α) = 5 2 = sin(α) = sin(α) = 5. os(α) = + c ot(α) = π)) sin( 60 ) sin( 60 ) sin(

[ ] Observability, Controllability תרגול 6. ( t) t t קונטרולבילית H למימדים!!) והאובז' דוגמא: x. נשתמש בעובדה ש ) SS rank( S) = rank( עבור מטריצה m

תרגול פעולות מומצאות 3

פתרון תרגיל 5 מבוא ללוגיקה ותורת הקבוצות, סתיו תשע"ד

מבני נתונים (234218) 1

לוגיקה ותורת הקבוצות פתרון תרגיל בית 8 חורף תשע"ו ( ) ... חלק ראשון: שאלות שאינן להגשה נפריד למקרים:

תוכן הפרק: ,best case, average case דוגמאות 1. זמן - נמדד באמצעות מס' פעולות סיבוכיות, דוגמאות, שיפור בפקטור קבוע האלגוריתם. וגודלם. איטרטיביים. לקלט.

מבני נתונים עצים שיעור 7

I. גבולות. x 0. מתקיים L < ε. lim אם ורק אם. ( x) = 1. lim = 1. lim. x x ( ) הפונקציה נגזרות Δ 0. x Δx

לדוגמה: במפורט: x C. ,a,7 ו- 13. כלומר בקיצור

מבני נתונים 08a תרגול 8 14/2/2008 המשך ערמות ליאור שפירא

כלליים זמן: S מחסנית, top(s) ראש המחסנית. (Depth First Search) For each unmarked DFS(v) / BFS(v) רקורסיבי. אלגוריתם :BFS

דוגמה: יהי T עץ בינארי כפי שמתואר בציור הבא:

אלגוריתמים בתורת הגרפים חלק ראשון

חידה לחימום. כתבו תכappleית מחשב, המקבלת כקלט את M ו- N, מחליטה האם ברצוappleה להיות השחקן הפותח או השחקן השappleי, ותשחק כך שהיא תappleצח תמיד.

מתמטיקה בדידה תרגול מס' 13

Logic and Set Theory for Comp. Sci.

תשובות מלאות לבחינת הבגרות במתמטיקה מועד ג' תשע"ד, מיום 0/8/0610 שאלונים: 315, מוצע על ידי בית הספר לבגרות ולפסיכומטרי של אבירם פלדמן

עץץץץ AVL. עץ AVL הוא עץ חיפוש בינארי שמקיים את התנאי הבא: לכל צומת x בעץ גורם האיזון של x הוא 1, 0, או 1-. הגדרה: במילים אחרות: לכל צומת x בעץ,

מבני נתונים ויעילות אלגוריתמים

( )( ) ( ) f : B C היא פונקציה חח"ע ועל מכיוון שהיא מוגדרת ע"י. מכיוון ש f היא פונקציהאז )) 2 ( ( = ) ( ( )) היא פונקציה חח"ע אז ועל פי הגדרת

יסודות לוגיקה ותורת הקבוצות למערכות מידע (סמסטר ב 2012)

מתמטיקה בדידה תרגול מס' 5

השאלות ידי מצביעים לילדים.

גבול ורציפות של פונקציה סקלרית שאלות נוספות

מיונים א': מיון (Sorting) HeapSort. QuickSort תור עדיפויות / ערימה

x a x n D f (iii) x n a ,Cauchy

ניהול תמיכה מערכות שלבים: DFfactor=a-1 DFt=an-1 DFeror=a(n-1) (סכום _ הנתונים ( (מספר _ חזרות ( (מספר _ רמות ( (סכום _ ריבועי _ כל _ הנתונים (

סיכום- בעיות מינימוםמקסימום - שאלון 806

סדרות - תרגילים הכנה לבגרות 5 יח"ל

הגדרה: קבוצת פעילויות חוקית היא קבוצה בה כל שתי פעילויות

חידה לחימום. כתבו תכנית שהקלט שלה הוא מספר שלם n,

לוגיקה ותורת הקבוצות פתרון תרגיל בית 4 אביב תשע"ו (2016)

. {e M: x e} מתקיים = 1 x X Y

' 2 סמ ליגרת ןורתפ םיפרגה תרותב םימתירוגלא דדצ 1 : הלאש ןורתפ רבסה תורעה

Hash Tables (המשך) ערבול (Hashing)

1 תוחלת מותנה. c ארזים 3 במאי G מדיד לפי Y.1 E (X1 A ) = E (Y 1 A )

שאלה 1 V AB פתרון AB 30 R3 20 R

תכנון אלגוריתמים 2016 עבודה 1 שאלה 1 פתרון נתונות שתי בעיות. יש למצוא: אורך מסלול קצר ביותר המתחיל באחד מן הקודקודים s 1,..., s k ומסתיים ב t.

חלק א' שאלה 3. a=3, b=2, k=0 3. T ( n) היותר H /m.

gcd 24,15 = 3 3 =

דף פתרונות 7 נושא: תחשיב הפסוקים: צורה דיסיונקטיבית נורמלית, מערכת קשרים שלמה, עקביות

TECHNION - ISRAEL INSTITUTE OF TECHNOLOGY DEPARTMENT OF COMPUTER SCIENCE סמסטר אביב תשס"ו מס' סטודנט:

פרק 13 רקורסיה רקורסיה רקורסיה רקורסיות פשוטות: חישוב עצרת. תמונת המחסנית ב-() factorial רקורסיות פשוטות: פיבונאצ'י

השאלות..h(k) = k mod m

אלגברה ליניארית (1) - תרגיל 6

קבוצה היא שם כללי לתיאור אוסף כלשהו של איברים.

לוגיקה ותורת הקבוצות מבחן סופי אביב תשע"ב (2012) דפי עזר

brookal/logic.html לוגיקה מתמטית תרגיל אלון ברוק

אלגוריתמים בתורת הגרפים חלק שני

{ : Halts on every input}

ניתוח סיבוכיות - פונקציות רקורסיביות פיתוח טלסקופי

c ארזים 26 בינואר משפט ברנסייד פתירה. Cl (z) = G / Cent (z) = q b r 2 הצגות ממשיות V = V 0 R C אזי מקבלים הצגה מרוכבת G GL R (V 0 ) GL C (V )

פתרון תרגיל 6 ממשוואות למבנים אלגברה למדעי ההוראה.

תרגול 1 חזרה טורי פורייה והתמרות אינטגרליות חורף תשע"ב זהויות טריגונומטריות

תכנון דינאמי. , p p p והמטריצה המתקבלת היא בגודל

co ארזים 3 במרץ 2016

חישוביות הרצאה 4 לא! זיהוי שפות ע''י מכונות טיורינג הוכחה: הגדרת! : f r

logn) = nlog. log(2n

אינפי - 1 תרגול בינואר 2012

מבני נתונים הגבלת אחריות פרק - 1 אלגוריתמי מיון ואנליזה אסימפטוטית. מיון בועות Sort Bubble מאת : סשה גולדשטיין,

תאריך הבחינה: שם המרצה: רפי כהן שם המתרגל: יסודות מבני נתונים שם הקורס:

Trie מאפשר חיפוש, הכנסה, הוצאה, ומציאת מינימום (לקסיקוגרפי) של מחרוזות.

אלגברה מודרנית פתרון שיעורי בית 6

סיכום בנושא של דיפרנציאביליות ונגזרות כיווניות

רשימת משפטים והגדרות

תורת הקבוצות תרגיל בית 2 פתרונות

תוכן עניינים I בעיות מיון 2 1 סימון אסימפטוטי... 2 II מבני נתונים 20 8 מבני נתונים מופשטים משפט האב גרפים... 37

מבני נתונים אדמיניסטרציה ד"ר אלכס סמורודניצקי, רוס 210, שני 5:30 4:15. ציון:

סיכום חקירת משוואות מהמעלה הראשונה ומהמעלה השנייה פרק זה הינו חלק מסיכום כולל לשאלון 005 שנכתב על-ידי מאיר בכור

3-9 - a < x < a, a < x < a

מבני נתונים מבחן מועד ב' סמסטר חורף תשס"ו

מודלים חישוביים תרגולמס 5

מבני נתונים מבחן מועד א' סמסטר חורף תשס"ו

תאריך עדכון אחרון: 27 בפברואר ניתוח לשיעורין analysis) (amortized הוא טכניקה לניתוח זמן ריצה לסדרת פעולות, אשר מאפשר קבלת

אלגוריתמים / תרגיל #1

לוגיקה ותורת הקבוצות מבחן סופי אביב תשע"ד (2014) דפי עזר

תרגיל 7 פונקציות טריגונומטריות הערות

אלגברה לינארית (1) - פתרון תרגיל 11

תרגול 8: מטלאב לולאות

s ק"מ קמ"ש מ - A A מ - מ - 5 p vp v=

מבני נתונים מבחן מועד א' סמסטר אביב תשס"ו

"קשר-חם" : לקידום שיפור וריענון החינוך המתמטי

Transcript:

גירסה 1.00 מבני נתונים מסמך זה הורד מהאתר. אין להפיץ מסמך זה במדיה כלשהי, ללא אישור מפורש מאת המחבר. מחבר המסמך איננו אחראי לכל נזק, ישיר או עקיף, שיגרם עקב השימוש במידע המופיע במסמך, וכן לנכונות התוכן של הנושאים המופיעים במסמך. עם זאת, המחבר עשה את מרב המאמצים כדי לספק את המידע המדויק והמלא ביותר. כל הזכויות שמורות ל Nir Adar Email: underwar@hotmail.com Home Page: עמוד 1

עמוד 2

1. תוכן עניינים 3 1. תוכן עניינים 5 5 5 5 6 הקדמה מהו מבנה נתונים מטרת המסמך ידע קודם נדרש הבדלים בין מסמך זה לבין סיכומי הנקודות.2.2.1.2.2.2.3.2.4 7 7 7 זמן ריצה של אלגוריתם הגדרת זמן הריצה של אלגוריתם סיבוכיות והסימון O.3.3.1.3.2 14 14 20 רקורסיה פתרון משוואות רקורסיביות ניתוח זמן ריצה של תוכניות רקורסיביות.4.4.1.4.2 24 24 25 25 26 מבני נתונים בסיסיים מחסנית תור דו תור מערך.5.5.1.5.2.5.3.5.4 32 32 33 33 36 36 37 רשימות מקושרות הגדרה רשימות עם כותרת מימוש רשימה מקושרת רשימה מקושרת דו כיוונית רשימה מעגלית רשימה מקושרת דו כיוונית חסכונית בזיכרון.6.6.1.6.2.6.3.6.4.6.5.6.6 38 38 39 44 45 47 51 56 58 עצים ועצי חיפוש הגדרות עצים בינאריים מילון עצי חיפוש עץ AVL עצי 3-2 עצי +B מידע נוסף בעצי חיפוש.7.7.1.7.2.7.3.7.4.7.5.7.6.7.7.7.8 63 63 66 רשימת דילוגים רשימת דילוגים רנדומאלית רשימת דילוגים דטרמיניסטית.8.8.1.8.2 עמוד 3

73 74 76 77 79 ערבול (HASHING) שיטת השרשראות - פתרון התנגשויות באמצעות רשימות מקושרות פתרון התנגשויות ללא רשימות מקושרות פונקציות ערבול ערבול אוניברסאלי.9.9.1.9.2.9.3.9.4 83 83 83 84 84 85 87 88 88 88 89 89 92 93 94 94 95 97 98 98 100 101 104 104 104 105 109 109 121 121 123 127 129 139 141 147 153 קבוצות זרות - FIND UNION.10 הגדרת הבעיה 10.1. מימוש ראשון: שימוש במערך 10.2. מימוש שני - רשימות מעגליות 10.3. מימוש שלישי - מערך מצביעים + רשימות מקושרות 10.4. מימוש רביעי - עצים הפוכים 10.5. שימוש אפשרי - יחסי שקילות 10.6. מיון 11. הגדרה - בעיית המיון 11.1. מוטיבציה לשימוש במיונים 11.2. מיון BUBBLE SORT.11.3 תור עדיפויות / ערימה 11.4. ערימת מינימום 11.5. מיון QUICKSORT.11.6 מציאת האיבר ה- I בגודלו (ללא מיון) 11.7. חסם תחתון למיון על ידי השוואות 11.8. מיון BUCKETSORT.11.9 מיון RADIXSORT.11.10 מבני נתונים למחרוזות 12. מבנה הנתונים TRIE 12.1. עץ סיומות TREE) (SUFFIX.12.2 עץ סיומות מוכלל 12.3. גרפים 13. גרפים מכוונים 13.1. גרפים לא מכוונים 13.2. מיון טופולוגי 13.3. תרגילים מסכמים 14. מערכת לניהול קורסים 14.1. נספחים 15. לוגריתמים, חזקות, סדרות חשבוניות והנדסיות 15.1. סיכום סיבוכיות מבני נתונים 15.2. אלגוריתמי מיון - טבלה מסכמת 15.3. מימוש של רשימה מקושרת דו כיוונית 15.4. מימוש מערך המאותחל ב-( O(1 15.5. מימוש של רשימת דילוגים 2-1 15.6. מימוש של עץ AVL 15.7. מימוש של עץ 3-2 15.8. עמוד 4

2. הקדמה 2.1. מהו מבנה נתונים מבנה נתונים זהו אוסף נתונים + פעולות המוגדרות על הנתונים. המשתמש במבנה הנתונים מכיר את הפעולות והשפעתן על הנתונים, אך הוא איננו נדרש להכיר את פרטי המימוש של הפעולות. באופן זה, הקוד של מבנה הנתונים יכול להיות מוחלף מבלי לפגוע בקטעי קוד המשתמשים בו. על ידי כך ניתן בזמן פיתוח של מערכת תוכנה לתכנן מימושים פשוטים ואחר כך להחליפם. כל תוכנית משתמשת במבנה נתונים על מנת לשמור את הנתונים שלה, ומכאן החשיבות של נושא זה. כאשר נבוא לדון במבני נתונים, נרצה להיות מסוגלים להשוות בין מבני נתונים, לדעת איזה מבנה נתונים יהיה היעיל ביותר עבור מטרה מסוימת, ונרצה להיות מסוגלים לנתח את היעילות של תוכנית. במסמך זה לא נסתפק בהצגה של מבני נתונים - כלומר הכרת התכונות שלהם והפעולות המוגדרות עליהם, אלא גם נכנס לתוך מבני הנתונים, נבין כיצד הם מתוכננים, וכיצד הם משיגים את היעילות שבגללה הם שימושיים עבורנו. 2.2. מטרת המסמך מטרת מסמך זה היא להכיר לקורא כ- 15 מבני נתונים בסיסיים, וכן אלגוריתמים שונים הקשורים אליהם. כמו כן המסמך בא לתת לקורא כלים המאפשרים לו לנתח את היעילות של הקוד שכתב: המסמך מציג את המתמטיקה הדרושה ואת דרכי החישוב של יעילות של תוכניות. 2.3. ידע קודם נדרש המסמך מניח שליטה בשפת C ובשפת ++C. החישובים וההוכחות המתמטיות מסתמכים על מתמטיקה בדידה ואלגברה מודרנית. עמוד 5

2.4. הבדלים בין מסמך זה לבין סיכומי הנקודות באתר "פרויקט "UnderWarrior מצויים זה מכבר ארבעה סיכומים בנושא מבנה נתונים, המכילים את הנושאים המוצגים במסמך זה. מסמך זה כולל את כל ארבעת הסיכומים, אולם הדגש בו שונה. בעוד שבארבעת הסיכומים ניסיתי לתמצת את הנושאים, ולהציגם בקיצור ובדייקנות ככל שניתן, במסמך זה הסברים רבים הורחבו על מנת שיהיו בהירים יותר, וכן הוספו דוגמאות רבות. מסמך זה מחליף למעשה את ארבעת המסמכים. בשנה האחרונה קיבלתי הצעות ותיקונים רבים למסמכים. התיקונים בוצעו, אך הם מופיעים במסמך זה בלבד. בחרתי להשאיר את המסמכים הישנים ללא שינוי ולהתרכז ביצירת משהו חדש ושלם יותר. כמו כן מסמך זה כולל הרחבות, דגשים מתמטיים, אלגוריתמים ומבני נתונים שלא הופיעו בסיכומים הקודמים. הנושא היחידי שנשאר כמעט ללא שינוי הוא נושא הגרפים. על נושא זה הרחבתי בסדרת מסמכים נפרדת, ולא ראיתי צורך להרחיב אותו גם במסמך זה. כתמיד, אשמח לקבל הצעות, הערות ותיקונים למסמך., יולי 2003 עמוד 6

3. זמן ריצה של אלגוריתם 3.1. הגדרת זמן הריצה של אלגוריתם זמן ריצה של אלגוריתם A עבור קלט x יסומן t. ( ) A זמן הריצה נמדד על ידי מספר פקודות מכונה x שהאלגוריתם מבצע על קלט נתון. מדד זה מתעלם מהבדלי מהירות בין ביצוע פקודות המכונה השונות (למשל חיבור לעומת כפל).. לדוגמא: בתוכנית המסכמת את איברי מערך x, גודל הקלט הוא מספר הגודל של קלט x יסומן ב- x איברי המערך. זמן הריצה הגרוע ביותר של אלגוריתם A עבור קלט שגודלו n מוגדר על ידי: ( A ) t ( n) = max t ( x) x = n A 3.2. סיבוכיות והסימון O הגדרה חסם עליון אסימפטוטי Ogn ( ( )) f( n) יהיו n) f( n), g( פונקציות חיוביות. נאמר שהפונקציה נמצאת בקבוצת הפונקציות g( n) כמו כן נאמר כי. f( n) c g( n) אם קיימים קבועים n, c 0 כך שלכל n0 n מתקיים: מהווה. f( n) = O( g( n)) חסם עליון אסימפטוטי לפונקציה (n )f ונסמן נשתמש בסימון זה כאשר הפונקציה היא פונקציה שקשה לתאר במדויק, בעוד ש- (n )g f( n) יותר. פשוטה עמוד 7

דוגמאות פולינום:. f n a an a n a n O n 2 k k ( ) = 0 + 1 + 2 +... + k טענה: עבור k קבוע, מתקיים ) ( =. f( n) c n k n0 n n, c 0 הוכחה: על מנת להוכיח את הטענה, נמצא קבועים נסמן: כך שלכל יתקיים:. amax = max 0, a0,..., ak k+ 1 k+ 1 2 k n 1 n. f( n) amax ( 1 + n+ n +... + n ) = amax amax = 2amaxn n 1 n/2 c=, n = 2, הרי שהטענה הוכחה. 2a 0 max k מתקיים: אם נבחר f( n) = log n= O(log n) a b לוגריתמי: עבור כל,a, b מתקיים: לכל > 0 ε מתקיים: f( n) = log n= O( n ε ) a ( ) k n n f( n) = n + a = O( a ) a> 1 n n f( n) = a = O( b ) ( b a) אקספוננציאלי n n תרגיל: האם הטענה הבאה נכונה: ) O(2. f( n) = 3 = פתרון: הטענה איננה נכונה. n. 3 < c 2 n n0 n n, c 0 נניח בשלילה שקיימים קבועים אי שוויון זה אינו מתקיים עבור כך שעבור יתקיים <n, וזאת בסתירה לטענה. log 1.5 c עמוד 8

הגדרה חסם תחתון אסימפטוטי Ω( g( n)) f( n) יהיו n) f( n), g( פונקציות חיוביות. נאמר שהפונקציה נמצאת בקבוצת הפונקציות g( n) נאמר כי. f( n) c g( n) n0 n n, c 0 אם קיימים קבועים תחתון אסימפטוטי לפונקציה כך שלכל ונסמן מתקיים: מהווה חסם. f( n) = Ω( g( n)) f( n) הגדרה - חסם הדוק אסימפטוטי יהיו n) f( n), g( פונקציות חיוביות.. f( n) =Ω( g( n)) f( n) = O( g( n)) נאמר שמתקיים n)) f( n) = Θ( g( אם מתקיים כי וגם הגדרה שקולה n0 n n0, c1, c2 נאמר שמתקיים n)) f( n) = Θ( g( אם קיימים קבועים כך שלכל מתקיים. c g( n) f( n) c g( n) 1 2 הגדרה זניחות אסימפטוטית ogn ( ( )) f( n) יהיו n) f( n), g( פונקציות חיוביות. נאמר שהפונקציה נמצאת בקבוצת הפונקציות. f( n) c g( n) n0 n n 0 אם לכל קבוע c קיים קבוע כך שלכל מתקיים: במקרה זה נאמר כי (n )f זניחה אסימפטוטית יחסית לפונקציה g. הגדרה שקולה f( n). lim = 0 n gn ( ) נאמר שמתקיים n)) f( n) = o( g( אם עמוד 9

מגבלות הסימון האסימפטוטי נוח להשתמש בסימונים אסימפטוטים מפני שהסימון מתעלם מקבועים ומאפשר ניתוח זמנים פשוט יותר. אולם, יש לזכור לשים לב לקבועים המסתתרים בסימונים אלו. נעדיף לעיתים שימוש בפונקציה בעלת זמן אסימפטוטי גדול יותר. שימוש בסימונים בדרך כלל נשתמש בסימונים, ΩΘ,O כדי לחסום את זמן הריצה של אלגוריתם מסוים. נתייחס אל זמן הריצה האמיתי של האלגוריתם כאל הפונקציה f בהגדרה, ואל החסם אותו אנו מחפשים כאל הפונקציה g באותה הגדרה. פעולות בסדרי גודל. f ( n) 2 f ( n) 1 נניח שנתונה תוכנית בה 2 לולאות: אחת לוקחת והשנייה לוקחת. f ( n) = O( g ( n)) 2 2 כמו כן, נניח כי n)) f ( n) = O( g ( וכי 1 1 1. אם הלולאות מופיעות אחת אחרי השנייה, אזי הזמן הכולל הוא סכום הזמנים:. f( n) = f ( n) + f ( n) 1 2. f( n) = f ( n) f ( n) 1 2 2. אם הלולאות מקוננות, אזי הזמן הכולל הינו מכפלת הזמנים:. f ( n) = O( g ( n) ) f 2 ( n) g 2 ( n) 1 1 3. לא תמיד מתקיים: עמוד 10

היררכיה של מחלקות סיבוכיות חסם קטגוריה O (1) קבוע O(log n ) 2 O(log n ) לוגריתמי... k O(log n ) On ( ) 2 On ( ) פולינומי... k On ( ) 2 log n O (2 )... O k n log (2 ) n O (2 ) n O (3 )... log On ( n ) = O(2 n n ) O... n 2 (2 ) תת אקספוננציאלי אקספוננציאלי אקספוננציאלי כפול עמוד 11

תרגיל מהי סיבוכיות הזמן של הקטעים הבאים כפונקציה של n (במושגים של θ)? (נסמן ב- (n )T את זמן הריצה של תוכנית עבור קלט n. א. scanf("%d",&n); sum = 0; for(i = n; i > 0; i--) k = i; while (k > i / 2) while (k > square - root(i)) k--; sum++; while (k>0) k--; sum++; פתרון. Θ 2 סיבוכיות הזמן הינה ) n ( הסבר: לולאת ה- for מתבצעת n פעמים. שתי לולאות ה- while מבצעות למעשה את אותו הדבר מקטינות את k עד שערכו שווה ל- 0, כך שבסך הכל אנחנו מבצעים i פעולות בכל איטרציה של הלולאה. נחשב את הסיבוכיות: n T n n n n n n n n n n n 2 2 2 2 ( ) = + ( 1) + ( 2) +... + ( ) = (1 + 2 +... + ) = (1 + ) =Θ( ) עמוד 12

ב. scanf("%d",&n); sum = 0; for(i = 2; i <= n; i++) for(j = i; j > 1; j /= 2) sum++; פתרון סיבוכיות הזמן הינה ((!n. Θ(log( הסבר: לולאת ה- for החיצונית מתבצעת 1 n פעמים. בכל איטרציה של הלולאה הפנימית אנחנו log2 מחלקים את j ב- 2 עד שערכו קטן מ- 1, כלומר מבצעים i פעולות חלוקה. ומכאן: Tn ( ) = log 2+log 3+...+log n=log n! =Θ (log( n!)) 2 2 2 2 ג. scanf("%d",&n); x = 2; while (x < n) x = x * x * x; ( ) 3 3 3 i 3 3 i x (0) = 2, xi ( ) = ( xi ( 1) ) = ( xi ( 2) ) =... = x(0) = 2 n < n i n T( n) = Θ (loglog n) 3 2 i i 3 log2 log3log2 פתרון נתבונן בערך של x בכל איטרציה: עמוד 13

4. רקורסיה 4.1. פתרון משוואות רקורסיביות הגדרה רקורסיה היא משוואה או שוויון המתארת פונקציה בעזרת ערכים שלה על ארגומנטים קטנים יותר. המטרה שלנו. Θ או O השגת כלים לפתירת משוואות רקורסיביות. בהינתן משוואה רקורסיבית, אנו רוצים לחסום את הפתרון למשוואה בעזרת גבולות דוגמא סיבוכיות הזמן של המיון Merge-Sort יכולה להיות מתוארת על ידי המשוואה הרקורסיבית הבאה: ( ) ( ) ( ) Θ 1 n = 1 Tn ( ) = 2 T n/2 +Θ n n> 1 פתרון משוואה זו הינו n). Tn ( ) =Θ( nlog נציג מספר שיטות לפתרון רקורסיות: שיטת ההצבה. שיטת האיטרציות. שיטת.master עצי רקורסיה. עמוד 14

שיטת ההצבה: מנחשים צורת פיתרון. משתמשים באינדוקציה מתמטית כדי למצוא קבועים ולהוכיח את נכונות הפתרון. דוגמא ( ) Tn ( ) = 2 T n/2 + n משוואה זו מזכירה את המשוואה המתאימה ל- Merge-Sort, ולכן טבעי לנחש כי פתרונה יהיה. c> 0, T( n) c nlog n יש להוכיח:. Tn ( ) = On ( log n) ( /2 ) 2 /2 log( /2 ) T n c n n, כלומר: נניח באינדוקציה כי הפתרון מתקיים עבור 2/ n נציב במשוואה הרקורסיבית: ( ) ( ) ( ) ( ) Tn ( ) = 2 T n/2 + n 2 c n/2 log n/2 + n cnlog n/2 + n= = cn log n cn log 2 + n = cn log n cn + n cn log n נשאר להוכיח שבסיס האינדוקציה מתקיים. אם נבחר = 1 (1) T ניתקל בביטוי לא הגיוני לצורך הוכחת n0 הסיבוכיות. כדי לעקוף את הבעיה, נעזר בעובדה כי הטענה צריכה להיות נכונה רק עבור < n מסוים. אם נבחר את (3)T,(2)T כבסיס לאינדוקציה, הרי שהטענה תתקיים. שיטת האיטרציות: בשיטה זו אין צורך לנחש פתרון. אנו פותרים את הביטוי הרקורסיבי כסכום של איברים שתלויים רק ב- n ובתנאי ההתחלה. שיטת הפעולה: מתחילים לפתוח את הביטוי, ומבינים כמה איטרציות צריכים לעשות כדי להגיע אל תנאי ההתחלה. בעזרת שני אלו מרכיבים ביטוי כללי המתאר את הרקורסיה. עמוד 15

דוגמא מצא חסם עליון אסימפטוטי עבור T(n) המופיעה בנוסחת הנסיגה הבאה. הנח כי T(n) קבועה עבור 1=n. Tn ( ) = Tn ( 1) n+ n פתרון Tn ( ) = Tn ( 1) n+ n ( ) i= 1 i= 0 ( ) Tn ( ) = Tn ( 1) n+ n= Tn ( 2) ( n 1) + ( n 1) n+ n= = T( n 2)( n 1) n+ ( n 1) n+ n= = T( n 3)( n 2) + ( n 2) ( n 1) n+ ( n 1) n+ n= = T( n 3)( n 2)( n 1) + ( n 2)( n 1) n+ ( n 1) n+ n= n n 1 n! 1 = = n! < e n! = O( n!) ( n i)! i! e, ולכן כאשר n זהו החסם העליון. n n 1 i= 0 1 i! הגבול כאשר הינו עמוד 16

a 1, b> ) ( fn, Tn ( ) = atnb ( / ) + כאשר 1 שיטת :master שיטה זו נותנת פתרון מיידי עבור רקורסיות מהצורה וגם n) f( היא פונקציה חיובית אסימפטוטית. רקורסיה מצורה זו מתארת זמן ריצה של אלגוריתם המחלק בעיה בגודל n ל- a תתי בעיות, שכל אחת f( n) מהן נפתרת בזמן (b )T. /n מייצגת את זמן חלוקת הבעיה וזמן איחוד התוצאות השונות. שיטת master מתבססת על המשפט הבא: f( n) קבועים, a 1, b> יהיו 1 פונקציה, ותהי (n )T המוגדרת על שלמים אי שליליים על ידי הנוסחה הרקורסיבית ) ( fn. Tn ( ) = atnb ( / ) +, והמשפט יתקיים. n/ b n/ ניתן לרשום במקום b /n או גם b הוכחת המשפט ארוכה (כ- 3 עמודים) וכן היא מסובכת, ולכן היא מושמטת ממסמך זה.. Tn ( ) =Θ a logb ( n ) (n )T אסימפטוטית באופן הבא: n), f( כאשר > 0 ε קבוע כלשהו, אזי = O n a logb ( ). Tn ( ) =Θ n logn אזי, f( n) =Θ a f ( n/ b) c f( n) קבוע כלשהו ואם ε כאשר > 0, f( n) =Ω אזי אפשר לחסום את a logb ε ( ) a logb ( n ) a logb +ε ( n ) אם אם אם עבור ( fn). Tn ( ) =Θ ( ) קבוע כלשהו, אזי c מסוים ועבור < 1 n> n 0.1.2.3 בשלושת המקרים משווים את עם (n )f צריכה להיות פולינומית n loga b. במקרים 3,1 f( n) > 0 ε כלשהו. גדולה/קטנה מ- n ε עבור פי n loga b המשפט אינו מכסה את כל האפשרויות עבור הוא מתאים. (n, )f אולם הוא מאפשר פתרון מהיר ביותר במקרים להם עמוד 17

דוגמא Tn ( ) = T(2 n/3) + 1 פתור את המשוואה הרקורסיבית הבאה: פתרון: ( n). Tn ( ) =Θ log. f( n) = 1 a= 1 b= 3/2 a logb ( n ) a 1 logb log 3/2 0 נסמן: = 1 n, n = n = ומכאן: =Θ(1) f( n) = Θ ולכן: עצי רקורסיה: עצי רקורסיה היא דרך נוחה להציג מה קורה במהלך הרקורסיה, וכך לפתור אותה. נדגים את השיטה בעזרת דוגמא. יש לפתור את המשוואה הרקורסיבית הבאה: n 2 ( ) = ( ) + T n 4T n logn 2 פתרון: n 2 log n n 2 log n n n 2 log 2 2 2 2 2 ( ) log ( ) ( ( ) ( ( ) ( n ) ( n ) 2 2 log 2 2 log 2 2 log 2 2 n n 2 log 4 2 2 n 2 n 2 n n n log n+ n log +... + n log = n log n+ log +... + log 2 n 2 n n log 2 times עמוד 18

נפתח את הביטוי שבסוגריים: log n + log n... log n log( n n... n ) 2 + + n = 2 n n n n lg n 1 1 1 1 lg n 1 lgn 1 n... = n... 0 1 2 n n n n lg lg n 2 1+ 2+ 4 +... + lg 2 4 n 2 2 2 = 2 2 2 = = 1(1 2 2 ) 1 2 1 n 2 2 lgn lg n = n = n 1 n 1 2 2 3 ( n ( log n ( n 1) log 2) ) ( n ) n n ( ( ( ) ( ))) log n 2 n 2 log 1 Tn ( ) =Θ n log =Θ n log n log 2 = n 1 2 =Θ =Θ כעת נציב שוב בביטוי הקודם. משפט (ללא הוכחה) תהי T(n) פונקציה. אם מתקיים ) ( On Tn ( ) = T( αn) + T( β n) + וגם < 1 β α + אזי T היא פונקציה ליניארית. משפט זה יכול לעיתים לתת פתרון מהיר למשוואה רקורסיבית. עמוד 19

4.2. ניתוח זמן ריצה של תוכניות רקורסיביות במקרים רבים ניתן להביע זמן ריצה של תוכנית רקורסיבית על קלט באורך n, כפונקציה של זמן ריצתה על קלטים קטנים יותר. כלומר, ניתן לבנות נוסחת נסיגה עבור זמן ריצת התוכנית, ולפתח את הנוסחה בשיטת הצבה חוזרת. דוגמא חישוב n! : Fact(n) אם = 0 n החזר 1 אחרת אחזר n 1). n Fact( פתרון: c1 n= 0 Tn ( ) = c2 + T( n 1) n> 0 T( n) = c + T( n 1) = c + c + T( n 2) = 2 c + T( n 2) =... = i c + T n i ( ) ( ) 2 2 2 2 2 התהליך יעצור כאשר נגיע ל-( 0 ) T (קבוע), ולכן תנאי העצירה הינו = 0 i. i = n n Tn ( ) = nc + T(0) = nc + c= On ( ) 2 2 1 נציב את התנאי בנוסחה שקיבלנו: עמוד 20

תרגיל מטריצה ריבועית A בגודל n על n נקראת ממוינת אם לכל 0>i<n היא מקיימת: A[i,j]<A[i,k] וגם A[j,i]<A[k,i] עבור כל 0>j<k<n (כלומר A ממוינת גם בשורות וגם בעמודות). לחיפוש איבר במטריצה ממוינת נשתמש באלגוריתם הבא: Find( x, A, i1, j1, i2, j2 ) begin if i1>i2 or j1>j2 Return; i1 + i2 i = 2 ; 1j + j2 j = 2 ; if A[i,j]=x then PrintToScreen( ìx was found at:î, i, j ); Stop; if A[i,j]>x then Find( x, A, i1, j1, i-1, j-1 ); Find( x, A, i1, j, i-1, j2 ); Find( x, A, i, j1, i2, j-1 ); else Find( x, A, i1, j+1, i, j2 ); Find( x, A, i+1, j1, i2, j ); Find( x, A, i+1, j+1, i2, j2 ); endif end א. ב. ג. ד. מה הסיבוכיות של האלגוריתם הנ"ל (כפונקציה של n) בקריאה ל- 1-n Find(,x,A,0,0,1-n (, כאשר A היא מטריצה ממוינת ו- x נמצא ב- A? הסבר. כתוב אלגוריתם שימצא את האבר המבוקש במטריצה ממוינת בזמן טוב ככל שתוכל (רמז: ניתן לעשות זאת ב- ).(O(n הסבר נכונות ועמידה בדרישות הסיבוכיות. הראה שהסיבוכיות שבסעיף ב' היא ) c o(n לכל קבוע 1<c. הראה שכל אלגוריתם דטרמיניסטי למציאת איבר במטריצה ממוינת ירוץ ב-( Ω(n זמן. עמוד 21

פתרון א. ניתן לראות כי הביטוי הבא מייצג את סיבוכיות האלגוריתם: c1 + 3 T( n/2) n> 1 Tn ( ) = c2 n= 1. c1, c 2 כאשר > 0 n log3 2 ε. f ( n) = const נפתור את הביטוי בעזרת שיטת.master ולכן היא חסומה על ידי מכאן כי ניתן ליישם את המקרה הראשון של משפט,master ולכן סיבוכיות האלגוריתם היא Θ log ( 3 2 ε n ) Find(x, A) 1. i n 1, j 0 ב. האלגוריתם: נניח לצרכי האלגוריתם כי האינדקסים בכל שורה מתחילים מ- 0. 2. While Aj [ ][ i] 3. If Aj [ ][ i] 4. If Aj [ ][ i] 5. If Aj [ ][ i] <> xand i 0 and j < n < xthen j j+ 1 > xthen i i 1 = xthen PrintToScreen( ìx was found at:î, i, j); עמוד 22

הסבר: אנו מתחילים את סריקת המטריצה מהפינה הימנית העליונה. בכל שלב: אם התא הנוכחי גדול מ- x (המספר המבוקש), סימן ש- x לא נמצא באף עמודה הימנית לעמודה הנוכחית, וכן לא בעמודה הנוכחית, ולכן אנו פונים עמודה אחת שמאלה. אם התא הנוכחי קטן מ- x, סימן ש- x לא נמצא באף אחת מהשורות מעל השורה הנוכחית, וכן לא בשורה הנוכחית, ולכן אנו יורדים שורה אחת מטה. הסריקה נעצרת כשאנו מגיעים לגבולות המטריצה, או שמצאנו את x. ניתוח סיבוכיות: מכיוון שבכל שלב אנו נעים צעד או שמאלה או למטה במטריצה, לאחר לכל היותר מגבולות המטריצה (כי אנו מתחילים בפינה הימנית העליונה, והמטריצה בגודל 2 n.( n n n= 2 צעדים. לפיכך, אם x לא נמצא במטריצה, האלגוריתם יסתיים לאחר (n )O צעדים נצא ג. סיבוכיות סעיף ב' הינה סיבוכיות סעיף ב' חסומה על ידי (n )O, ולכן עלינו להוכיח כי הביטוי שווה ל- 0 כדי להוכיח כי cn 1 lim n n c c.o( n) cn = cn = n lim 1 lim 1 c 0 c 1 n n c> 1 ד. זמן הריצה הוא לא. (n )Ω כי עלינו לבדוק לפחות את כל האלכסון כדי לדעת אם איבר נמצא במטריצה או בכל בדיקה אנו יכולים להגיד במקרה הטוב ביותר האם האיבר לא נמצא בשורה ובעמודה הנוכחיים. מכיוון שיש לנו n עמודות ו- n שורות, שהינם בלתי תלויים, אנו חייבים לבדוק לפחות כל שורה או כל עמודה, ולכן לבצע לפחות n צעדים. לפיכך זמן הריצה הוא.Ω( n) עמוד 23

5. מבני נתונים בסיסיים מבנה נתונים זהו אוסף נתונים + פעולות המוגדרות על הנתונים. המשתמש במבנה הנתונים מכיר את הפעולות והשפעתן על הנתונים, אך הוא איננו נדרש להכיר את פרטי המימוש של הפעולות. באופן זה, הקוד של מבנה הנתונים יכול להיות מוחלף מבלי לפגוע בקטעי קוד המשתמשים בו. על ידי כך ניתן בזמן פיתוח של מערכת תוכנה לתכנן מימושים פשוטים ואחר כך להחליפם. 5.1. מחסנית מחסנית היא מבנה נתונים בו "אחרון נכנס ראשון יוצא" Out).(Last In First מחסנית מוגדרת על ידי הפעולות הבאות: תיאור פעולה מחזיר מחסנית S ריקה חדשה create(s) מכניס איבר בעל ערך x למחסנית S push(s, x) מחזיר את האיבר שבראש המחסנית S top(s) מוציא את האיבר שבראש המחסנית S pop(s) מחזיר true אם S ריקה ו- false אחרת. is-empty(s) מימושים אפשריים למחסנית: 1. באמצעות רשימה מקושרת חד כיוונית. אנו מחזיקים מצביע אל ראש הרשימה. כל פעולות ההכנסה וההוצאה מהרשימה מתבצעות על הראש בלבד. 2. מערך בגודל N, עם "מצביע" לראש המבנה. (כאשר מממשים בצורה זו, מקובל להגדיר משתנה מסוג,int השומר את האינדקס של האיבר שבראש המחסנית). המצביע מצביע תמיד על המקום הפנוי הראשון במערך. בתחילת העבודה הוא מצביע אל האיבר הראשון. אנו משתמשים במימוש זה, כאשר ידוע על חסם N על מספר האיברים במבנה. סיבוכיות הזמן של הפעולות המוגדרות על המבנה הינה (1)O. סיבוכיות המקום היא (n )O במימוש עם רשימה, כאשר n הינו מספר האיברים במבנה. במימוש עם מערך, סיבוכיות המקום היא (N )O. עמוד 24

5.2. תור תור היא מבנה נתונים בו "ראשון נכנס ראשון יוצא" Out).(First In First תור מוגדר על ידי הפעולות הבאות: תיאור פעולה מחזיר תור ריק create(q) מחזיר את ערך האיבר שבראש התור Q (התור אינו משתנה ( head(q) Q לסוף התור x מכניס איבר עם ערך enqueue(q, (x Q מוציא את האיבר שבראש התור dequeue(q) מחזיר true אם Q ריק ו- false אחרת. is-empty(q) מימושים אפשריים לתור:.1.2 רשימה מקושרת חד כיוונית עם שני מצביעים: head לראש הרשימה ו- tail לזנבה. הכנסות של איברים חדשים מתבצעות בזנב הרשימה והוצאות איברים מתבצעות בראש הרשימה. מערך בגודל N עם שני "מצביעים": head ו- tail, כאשר tail יצביע תמיד על המקום הפנוי הראשון ו- head על המועמד הראשון להוצאה מהמבנה. בתחילת העבודה שניהם מצביעים אל התא הראשון. סיבוכיות הזמן של הפעולות המוגדרות על המבנה הינה (1)O. סיבוכיות המקום היא (n )O במימוש עם רשימה, כאשר n הינו מספר האיברים במבנה. במימוש עם מערך, סיבוכיות המקום היא (N )O. 5.3. דו תור דו תור מוגדר על ידי הפעולות הבאות: תיאור פעולה מחזיר דו תור ריק. create(q) מכניס איבר עם הערך x לראש המבנה. (x insert_head(q, מכניס איבר עם הערך x לזנב המבנה. (x insert_tail(q, מוציא את האיבר שבראש המבנה. delete_head(q) מוציא את האיבר שבזנב המבנה. delete_tail(q) מחזיר את ערך האיבר שבראש המבנה. read_head(q) מחזיר את ערך האיבר שבזנב המבנה. read_tail(q) מחזיר true אם המבנה ריק. is-empty(q) עמוד 25

מימושים אפשריים לדו תור: 1. רשימה מקושרת דו כיוונית עם שני מצביעים: head לראש הרשימה ו- tail לזנבה. 2. מערך בגודל N עם שני "מצביעים": head ו- tail. נשתמש במימוש הנ"ל כאשר ידוע חסם N על מספר האיברים במבנה. מילוי המערך יתבצע בצורה ציקלית. מימוש הפעולות הוא בדומה למימושן עבור תור ומחסנית. סיבוכיות הזמן של הפעולות המוגדרות על המבנה הינה (1)O. סיבוכיות המקום היא (n )O במימוש עם רשימה, כאשר n הינו מספר האיברים במבנה. במימוש עם מערך, סיבוכיות המקום היא (N )O. 5.4. מערך מערך מוגדר על ידי הפעולה הבאות: תיאור פעולה מחזיר מערך A של איברים מטיפוס type כאשר האינדקסים הם הקבוצה (I create(type, הסופית I.. A בתוך המערך i I מחזיר את הערך של האיבר עם האינדקס get(a, i). e את ערך הביטוי, i I תחת האינדקס,A מאחסן במערך store(a, i, e) כללים הנשמרים על ידי הפעולות כל הערכים במערך הם מאותו טיפוס, והוא נקבע בהצהרה.(type) הערך המאוחזר לפי אינדקס i, הוא הערך האחרון שנישמר לפי אינדקס i. אחזור לפי אינדקס i מחזיר ערך בלתי מוגדר אם מעולם לא אוחסן ערך לפי אינדקס זה. כל הפעולות מתבצעות ב-( O(1. עמוד 26

מערך דו ממדי type A[m][n]; כל שורה A[i] היא מערך חד ממדי באורך n. מערך דו ממדי יכול להיתפס כמטריצה, או כטבלה הנמצאת בזיכרון. אם נניח כי base היא הכתובת של [0][0]A, וכי המימוש של המערך הממדי הוא באזור זיכרון רצוף, אזי הכתובת של השורה A[i] היא. base + i n הכתובת של האיבר A[i][j] היא. base + i n + j מערך רב ממדי Ai [ 3][ i2][ i1] נרחיב את מה שראינו לגבי מערך דו ממדי: An [ במערך תלת ממדי [n1 ][3 ][n2 הכתובת של האיבר מחושבת על ידי הנוסחה n] An [ ]...[ n][ n][ הכתובת של d 3 2 1. base + i n n + i n + i באופן דומה, עבור מערך רב ממדי 3 2 1 2 1 1. base + i n... n + i n... n +... + i d d 1 1 d 1 d 2 1 1 i] Ai [ ]...[ i][ i ][ מחושבת על ידי הנוסחה d 3 2 1 : Ai [ ]...[ i][ i ][ i] d 3 2 1 התוכנית הבאה מחשבת את הכתובת של addr=i[d]; for (j = d 1; j >= 1; j--) addr = addr * n[j] + i[j]; addr = base + addr; זמן סריקת כל איברי מערך [n An [ ]...[ ][n ][n תלוי בסדר הסריקה. d 3 2 1 סריקה לפי סדר האחסון מהירה יותר בגלל לוקליות של גישה לזיכרון. סריקה בה אינדקסים נמוכים נסקרים ראשונים מהירה יותר מסריקה בה אינדקסים גבוהים נסרקים ראשונים. השיפור הוא בקבוע בלבד ואינו מתבטא בסימון O. עמוד 27

אתחול מערך בזמן (1)O הבעיה: בייצוג רגיל אתחול מערך דורש זמן.O(n) נרצה למצוא ייצוג של מערך שיאפשר לאתחל מערך בזמן (1)O. בתמורה לשיפור זה נשתמש ביותר זיכרון. 5 4 3 2 1 0 המציינים המוגדרים מצביעים לאיזור הבטוח 333 7 222 111 3 5 5 4 3 2 1 0 237 0 753 554 1 2 564 121 123 0 1 4 5 4 3 2 1 0 ערכים A B C Top נגדיר שלושה מערכים: מערך A הינו מערך הערכים. מערך B הינו מערך מצביעים לאזור הבטוח במערך C. מערך C הוא מערך המציינים המוגדרים. בנוסף נגדיר משתנה top שיכיל את האינדקס של האיבר הראשון במערך C המכיל זבל, וכן משתנה constant אשר יכיל ערך ברירת מחדל עבור התאים השונים. האזור הבטוח במערך C, הוא כל האיברים שהאינדקס שלהם קטן מהאינדקס של.top הקשר בין מערך B למערך C הוא כלהלן: C. הוא מערך שכל תא בו מכיל אינדקס במערך B במידה ונרצה לקבל את האיבר A[i] במערך A, נבדוק ראשית את האיבר.B[i] איבר זה מכיל אינדקס במערך C. אם אינדקס זה קטן מ- top וגדול מ- 0, יתכן שזהו אינדקס חוקי. אם בתא C[B[i]] קיים האינדקס של האיבר ב- B, אזי הערך ב- A הינו ערך חוקי. (נשים לב שללא המשתנה top זה לא היה נכון בכל המקרים). עמוד 28

נציג קטעים ממימוש ב- C של מערך כזה. בנספחים ניתן למצוא מימוש מלא של מערך המאותחל ב-( O(1 בשפת ++C: הקוד לאיתור זבל: int is_garbage(int i) return! ( ( B[i] < top && (B[i] >= 0) && (C[B[i]] == i) ); אתחול const) :init(v, top = 0; constant = const; אחזר i) :get(v, if (is_garbage(i)) return constant; else return A[i]; שמור e) :store(v, i, if (is_garbage(i)) C[top] = i; B[i] = top; top += 1; A[i] = e; כל הפעולות מתבצעות בסיבוכיות זמן (1)O. עמוד 29

מטריצות דלילות מטריצה דלילה היא מערך דו ממדי עבורו "רוב מוחלט" של האיברים שווה לאפס (או לקבוע c) כלשהו. M,..., 1 M n נגדיר את "הרוב המוחלט" בצורה אסימפטוטית: אם סידרת המטריצות מקיימת שמספר האיברים השונים מקבוע c הוא מסדר גודל של o(m(n)) כאשר m(n) הוא מספר המקומות המקסימאלי במטריצה, M n אזי זוהי סידרה של מטריצות דלילות. למשל: מטריצות אלכסוניות הן מטריצות דלילות. 2 )o. (n הוא c מספר האיברים השונים מקבוע, n במטריצות ריבועיות דלילות מגודל n במקום לשמור את המטריצה כמערך דו ממדי רגיל, נציע פיתרון אחר לייצוג מטריצות דלילות: רשימה של שלשות ( i, j, Aij ) המסודרות בסדר לקסיקוגרפי. דוגמא: ) 1,5,7 ),( 2,10 ),( 0, 0,1,2.( חסרון עיקרי של הייצוג: אין גישה אקראית לאיבר ב-( O(1. יתרונות: חוסך בזיכרון עבור מטריצות דלילות, מאיץ פעולות חיבור וכפל של מטריצות דלילות. n חיבור מטריצות בגודל n לוקח בייצוג רגיל 2 (n )O. עבור מטריצות דלילות זמן החיבור הוא 2.o( n) מטריצת אלכסונים מטריצת אלכסונים היא מטריצה ריבועית שבה לאורך כל אלכסון כל האיברים הם זהים. לדוגמא: 3 5 1 4 7 8 3 5 1 4 5 8 3 5 1 0 5 8 3 5 6 0 5 8 3, M המסוגל לבצע את הפעולות הבאות: n n נרצה להציע מימוש למבנה נתונים עבור מטריצת אלכסונים. M במטריצה,i j החזר את תוכן האיבר הנמצא באינדקס get(i, (j (x put(i,,j הצב את הערך x ל-[ j. ][]M i עדכן גם את שאר האיברים באלכסון לערך החדש. עמוד 30

.O( n) מימוש 1: נממש את מטריצת האלכסונים כמערך דו ממדי. סיבוכיות הזמן של פעולת (j get(i, היא (1)O, וסיבוכיות הזמן של פעולת (k put(i,,j הינה סיבוכיות המקום של מבנה הנתונים הינה 2.O( n) מימוש 2: נשמור איבר אחד בלבד עבור כל אלכסון. סה"כ המאופיין על ידי 2n 1 j, הערך המתאים יאוכסן בתא i איברים. נקצה מערך A בגודל זה. עבור אלכסון, [ + ( 1) ]. A j i n על מנת לשנות את ערך האלכסון, פשוט ניגש אל התא המתאים ונשנה את תוכנו. על מנת להחזיר את תוכן התא, פשוט נחזיר את תוכן התא המתאים לתא במערך A. לפיכך, במימוש זה, סיבוכיות הזמן של פעולת (j get(i, היא (1)O, וסיבוכיות הזמן של פעולת )O. (n סיבוכיות המקום של מבנה הנתונים הינה (1)O. הינה put(i,,j (k מימוש זה עדיף על המימוש הראשון הן בסיבוכיות הזמן שלו והן בסיבוכיות הזיכרון. עמוד 31

6. רשימות מקושרות 6.1. הגדרה רשימה מקושרת היא סידרת רשומות, אשר בכל אחת מהן יש שדה המצביע לרשומה הבאה. הגדרה של רשומה אחת ב- C : struct element TYPE info; struct element *next; ; רשימה מקושרת מוגדרת על ידי הפעולות הבאות: פעולה init() find(x, head) delete(t) insert(t, x) תיאור מחזיר רשימה מקושרת חדשה וריקה. סיבוכיות: (1)O. חיפוש האיבר x ברשימה המקושרת. סיבוכיות: n).o( הפרמטר t מצביע לצומת שלפני הצומת אותה רוצים להוציא. מחיקת הצומת הבאה אחרי t סיבוכיות: (1)O. הפרמטר t מצביע לצומת שלאחריו נוסיף צומת חדש. הוספת האיבר x לרשימה המקושרת. סיבוכיות: (1)O. יתרונות בהשוואה למערך: מאפשר הקצאת זיכרון דינאמית. איך צורך להקצות מקום זיכרון רצוף. ניתן להוציא איבר מתוך רשימה מקושרת מבלי להשאיר "חור" כמו במערך, ולכן ניתן לסרוק את כל האיברים בזמן ליניארי. עמוד 32

חסרונות ביחס למערך אין גישה לפי אינדקס בזמן (1)O 6.2. רשימות עם כותרת נהוג להגדיר כותרת (header) לרשימה מקושרת. כותרת זוהי רשומה ראשונה ברשימה, אשר לא מהווה איבר ברשימה. תפקידה להצביע בשדה ה- next שלה על האיבר הראשון ברשימה. בעזרת הכותרת ניתן להימנע מהתייחסות מיוחדת למקרים בהם פעולה כלשהי מופעלת על האיבר הראשון. בצורה כזו נוכל לפשט בצורה ניכרת את הפונקציות הפועלות על הרשימה. רשימה עם כותרת חוסכת: טיפול מיוחד ברשימות ריקות. טיפול מיוחד בהכנסת איבר לפני האיבר הראשון / מחיקת האיבר הראשון. 6.3. מימוש רשימה מקושרת נציג כעת מימוש אפשרי של רשימה מקושרת בשפת C. בנספח א' קיים מימוש של רשימה מקושרת מורחבת, הכתוב בשפת ++C. הרשימה היא רשימה עם כותרת, על מנת להימנע ממקרי הקצה. הצהרות שונות: typedef struct element* NODE; typedef int RESULT; #define FAIL 0 #define SUCCESS 1 עמוד 33

אתחול רשימה ריקה: /* Creates new list and returns pointer to its header */ NODE init() NODE header; header = (NODE)malloc(sizeof(struct element)); if (header == NULL) return NULL; header->next = NULL; return header; הכנסת איבר לרשימה: /* Insert node to the beginning of the list with the value x */ RESULT insert(node plistheader, TYPE x) NODE newnode; if (plistheader == NULL) return FAIL; newnode = (NODE)malloc(sizeof(struct element)); if (newnode == NULL) return FAIL; newnode->info = x; /* Make the new node point to the first element of the linked list */ newnode->next = plistheader->next; /* Set the first item of the list to be the new node */ plistheader->next = newnode; return SUCCESS; עמוד 34

מחיקת איבר מהרשימה: /* The function gets pointer to the node BEFORE the node we want to delete, and deletes the following node */ RESULT remove(node t) NODE temp = t->next; if (t == NULL t->next == NULL) return FAIL; t->next = t->next->next; free(temp); return SUCCESS; מציאת איבר ברשימה: /* Gets pointer to the list header and a requested key, and returns pointer to the node BEFORE the node with that key, or NULL if there is no such node */ NODE find(node plistheader, TYPE x) NODE it; for (it = plistheader; it!= NULL; it = it->next) if (it->next == NULL) return NULL; if (it->next->info == x) break; return it; שחרור כל הזיכרון של הרשימה, בסיום העבודה עימה: /* Gets a list and delete all its data */ void dispose(node plistheader) NODE cur = plistheader, temp; while (cur!= NULL) temp = cur; cur = cur->next; free(temp); עמוד 35

6.4. רשימה מקושרת דו כיוונית רשימה מקושרת דו כיוונית מוגדרת בדומה לרשימה מקושרת חד כיוונית, פרט לכך שכל רשומה בה מכילה שתי שדות של מצביעים: מצביע לאיבר הבא (next) ומצביע לאיבר הקודם.(prev) משתמשים במבנה נתונים זה במקרים בהם יש צורך לגשת מרשומה כלשהי במבנה גם קדימה וגם אחורה. כמו כן ניתן לפשט קצת את פעולות הרשימה כאשר אנו משתמשים ברשימה דו כיוונית - למשל, delete ו- find יכולות להחזיר מצביע אל האיבר עצמו, ולא אל האיבר שלפניו (כי אנו מסוגלים כעת בהינתן צומת כלשהו T, לגשת ב-( O(1 אל האיבר שלפניו). 6.5. רשימה מעגלית רשימה מעגלית מוגדרת כרשימה חד כיוונית, בה האיבר האחרון מצביע אל האיבר הראשון. השימוש ברשימה מעגלית נעשה כאשר מבצעים סיורים ציקליים במבנה. גם ברשימה רגילה ניתן לסייר בצורה ציקלית, אך זה כרוך בטיפול מיוחד עבור המקרה של השגת קצה הרשימה. יתרון בשימוש ברשימות מעגליות הוא ניתן לשרשר רשימות מעגליות בזמן קבוע. הוצאת איבר מרשימה hack בהינתן מצביע t אל איבר ברשימה חד כיוונית, האם ניתן להוציא את האיבר? ניתן על ידי טריק נעתיק את האינפורמציה בתא העוקב לt אל התא t, ונוציא את התא העוקב. לשיטה זו מספר חסרונות: צומת יכול להכיל הרבה מידע, ולכן פעולת העתקה עלולה להיות פעולה ארוכה. יתכן וישנם מצביעים נוספים המצביעים לתא שאנו מוציאים ואין לנו אפשרות לעדכן מצביעים אלו. תזכורת - חוקי XOR a 0 = a a a = 0 a b= b a ( a b) c= a ( b c).1.2.3.4 עמוד 36

6.6. רשימה מקושרת דו כיוונית חסכונית בזיכרון נרצה למצוא דרך ליצור רשימה מקושרת דו כיוונית תוך שימוש במצביע אחד בכל צומת ולא בשני מצביעים. נשתמש בעובדה שנתונים ברשימה למעשה משוכפלים - ה- next של צומת אחד הוא ה- prev X i של צומת אחר. במקום לשמור שדה next או,prev נשמור עבור הצומת את הצירוף הבא: ( i) = i 1 i+ 1 L X X X נביא דוגמא להמחשה. יהיו,N,P,Q R צמתים עוקבים ברשימה מקושרת. N P Q R נניח שיש בידינו את הכתובות,N,,P,Q R על מנת לראות כיצד ניתן לחשב בעזרת כתובת אחת את הכתובת האחרת. נביט בביטוי L( P) Q= N Q Q= N : L( P) Q כלומר בעזרת כתובתו של Q ובעזרת המידע השמור ב- L( P) קיבלנו את הכתובת של N. בצורה דומה מתקיים:. P LQ ( ) = R Temp P P Q Q Temp L( Q) צעד קדימה: נניח שישנם בידינו רק המצביעים,P, Q ונרצה להזיזם קדימה. נבצע את הפעולות הבאות: לפיכך, אם נחזיק כל הזמן שני מצביעים - אחד לאיבר הנוכחי ושני לאיבר הבא/הקודם, נוכל לממש הליכה קדימה ואחורה על הרשימה - ולממש למעשה רשימה מקושרת דו כיוונית. מסקנה: מכיוון שברשימה דו כיוונית הסטנדרטית אנו מצביעים פעמיים על אותה כתובת, "תכונת גודש", אנו מסוגלים לחסוך בזיכרון. עמוד 37

7. עצים ועצי חיפוש 7.1. הגדרות גרפים לא מכוונים ( V, גרף לא מכוון הוא זוג (E בת שני איברים מתוך V. קשת מסומנת על ידי המורכב מקבוצת צמתים V ומקבוצת קשתות E. קשת ב- E היא קבוצה.( i, j) m=. n= V, מתקיים: נסמן: E 2 מספר הקשתות m קטן בכל גרף מ-. n דוגמא ל- E,V: V = a, b, c, d, e (, ),(, ),(, ),(, ),(, ),(, ),(, ) E = ab ad bc be cc de ce הקשת ), cc ( נקראת חוג עצמי. גרפים מכוונים E V V ( V, גרף מכוון הוא זוג (E מסלול מכוון בגרף מכוון המורכב מקבוצת צמתים V וקבוצת קשתות ( v v v ),,..., k 1 2 הוא סידרת צמתים כך שלכל זוג צמתים עוקבים. v גרף התשתית של גרף = v 1 k ( V, E) (, ) vi v i + 1 בסדרה, היא קשת ב- E. המסלול נקרא מעגל מכוון, אם מכוון G הוא גרף לא מכוון עם אותם צמתים כמו ב- G, ואותם קשתות כמו ב- G, אך ללא כיוון. עמוד 38

עצים מכוונים מקור הוא צומת שאף קשת אינה מצביעה אליו. עץ מכוון הוא גרף מכוון ללא מעגלים (בגרף המקור שלו) ואשר לו מקור אחד בלבד הנקרא שורש. ל- v. u אם קיים מסלול מכוון מצומת u צאצא של v u. צאצא של v אם v אב קדמון של u תת עץ של G ששורשו v הוא תת עץ מכוון שצמתיו הם v עצמו וכל הצאצאים של v, והקשתות שלו הן הקשתות המחברות צמתים אלו ב- G. דרגת צומת v היא מספר הבנים של v. עלה הוא צומת ללא בנים. צומת פנימי הוא צומת שאינו עלה. עומק של צומת v הוא מספר הקשתות משורש העץ אל v. גובה של צומת v הוא מספר הקשתות מv לצאצא הרחוק ביותר של v (עלה). גובה העץ הוא הגובה של שורש. עץ מסודר הוא עץ מכוון שבו הבנים של כל צומת מסודרים (משמאל לימין). כלומר, הסדר בין כל שני בנים קובע עצים שונים (גם אם אלו בנים של אותו האב). 7.2. עצים בינאריים עץ בינארי הוא עץ שבו לכל צומת שאינה עלה יש בן שמאלי ו/או בן ימני. הגדרה רקורסיבית לעץ בינארי: עץ בינארי הוא מבנה: 1. ריק (ללא צמתים) או 2. מורכב משלושה חלקים: צומת הנקרא שורש, עץ בינארי הנקרא תת עץ שמאלי, ועץ בינארי הנקרא תת עץ ימני. עץ בינארי מלא הוא עץ בינארי בו לכל צומת פנימי 2 בנים. עץ בינארי שלם הוא עץ בינארי מלא בו כל הבנים באותו עומק. עץ בינארי כמעט שלם הוא עץ בינארי שלם שהוצאו ממנו עלים "מצד ימין". עמוד 39

תכונות של עצים בינאריים שלמים: יהיה עץ בינארי שלם, בעל n צמתים, L עלים וגובה h, אזי. n i = 1. מספר הצמתים בעומק i הוא 2 i. L = n h = 2. מספר העלים הוא 2 h h h i h+ 1 ni 2 2 1 i= 0 i= 0.3 מספר הצמתים בעץ הוא = = n=.. h= log ( n+ 1) 1 2 4. הגובה של העץ: h.5 מספר הצמתים הפנימיים הוא L 1. n L= 2 1= ייצוג עצים בינאריים שלמים בעזרת מערך ניתן לייצג עץ בינארי שלם במערך. אחד היתרונות של ייצוג כזה הוא גישה לכל אחד מאיברי העץ בזמן (1)O בהינתן האינדקס שלו. a 1 b 2 3 c d 4 5 e f 6 g 7 h i j k l m n o 8 9 10 11 12 13 14 15. 2i נמצא ב- i. 2i נמצא ב- 1 + i הבן השמאלי של צומת הבן הימני של צומת האבא של צומת i נמצא ב- 2 / i. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 o n m l k j i h g f e d c b a עמוד 40

סיור בעצים בינאריים נביט בשלושה סוגי סיורים, השונים ביניהם בסדר בו אנו ניגשים לבנים של כל צומת ואל הנתונים בכל צומת. preorder בקר בשורש סייר בתת העץ השמאלי סייר בתת עץ הימני postorder סייר בתת העץ השמאלי סייר בתת עץ הימני בקר בשורש inorder סייר בתת העץ השמאלי בקר בשורש סייר בתת עץ הימני מימוש של צומת של עץ בינארי בשפת C הוא כלהלן: struct node int value; struct node *left, *right; ; typedef struct node* NODE; עמוד 41

מימוש לדוגמא של :postorder void postorder(node T) if (T == NULL) return; else postorder(t->left); postorder(t->right); do_operation_on_t; דוגמא לסיור postorder היא חישוב גובה של עץ נתון: int height(node T) int L, R; if (T == NULL) return -1); else L = height(t->left); R = height(t->right); return 1 + max(l, R); דוגמא נוספת: חישוב מספר הצמתים בעץ. int count(node T) if (T == NULL) return 0; return 1 + count(t->left) + count(t->right); עמוד 42

n 0 נסמן ב- נוכיח כעת טענות לגבי עצים בינאריים. נשתמש בהצגתן בסימונים הבאים: יהי העץ T. את מספר הצמתים בעץ שאין להם בנים, ב- את מספר הצמתים בעלי בן אחד וב- n 2 את מספר הצמתים בעלי שני בנים. n 1 טענה 1. n 0 עבור כל עץ,T מתקיים = n2 + 1 n= n + n + n 0 1 2 n= E+ 1= n + 2n + 1 E = n + 2n 1 2 1 2 הוכחה 1 n 0 = n2 + 1 טענה 2 בעץ יהיו תמיד 1+ n מצביעים ריקים. 2n + n = n + n + 1+ n = n+ 1 0 1 0 2 1 הוכחה 2 עמוד 43

7.3. מילון מילון הוא מבנה נתונים המאחסן אוסף של רשומות מהטיפוס: [מפתח, אינפורמציה]. המפתח שונה מרשומה לרשומה. אוסף כל המפתחות האפשריים מסומן ב- U. פעולות המוגדרות על מילון: פעולה תיאור create(d) אתחול, יצירות מילון ריק find(d, (x חיפוש מחזיר מצביע לרשומה בD שמפתחה הוא x או.NULL insert(d,,x info) הוספה הוסף ל- D רשומה שמפתחה x. delete(d, (x הוצאה סלק מ- D רשומה שמפתחה x. כללים: U. שייך לקבוצת המפתחות x כל x מופיע לכל היותר פעם אחת במילון. כאשר מוגדר סדר על U (למשל, כאשר מפתח הוא מספר), מוגדרות פעולות נוספות על מילון: פעולה תיאור min(d) מינימום החזר את המפתח המינימאלי ב- D next(d, (x עוקב החזר מצביע לאיבר במילון D בעל המפתח הקטן ביותר שגדול מ- x. עמוד 44

7.4. עצי חיפוש עצי חיפוש היא משפחה של מימושים למבנה הנתונים "מילון" כאשר מוגדר סדר על קבוצת המפתחות U. עץ חיפוש בינארי נשתמש בעץ בינארי מכוון כעץ חיפוש. בכל צומת נאחסן רשומה אחת מתוך מילון (או מפתח ומצביע לאינפורמציה של הרשומה). נשמור על הכלל הבא: עבור צומת כלשהו בעל מפתח x, כל המפתחות בתת העץ השמאלי קטנים מ- x וכל המפתחות בתת העץ הימני גדולים מ- x. אלגוריתם חיפוש איבר (x find(t, אם T ריק, דווח ש- x לא בעץ. יהי y הערך בשורש. אם,x=y החזר מצביע לצומת המחזיק את x. אם,x<y המשך את החיפוש בתת העץ השמאלי. אם x>y המשך את החיפוש בתת העץ הימני..1.2.3.4.5 אלגוריתם הכנסה חפש את x בעץ החיפוש T. אם x נמצא ב- T, עצור ודווח. יהי V הצומת האחרון במסלול החיפוש של x ויהי y המפתח שנמצא בv. אם,x<y הוסף צומת w עם מפתח x כבן שמאלי של v. אחרת (כאשר,(x>y הוסף צומת w עם מפתח x כבן ימני של v..1.2.3.4.5 עמוד 45

אלגוריתם הוצאה אם v עלה, סלק אותו. אם לv בן יחיד, תן לאבא של v להצביע על הבן. אחרת: יהי w הצומת העוקב ל- v בסדר inorder (הצומת המתקבל על ידי פניה אחת ימינה ואחר כך כל הדרך שמאלה). שים בצומת v את המפתח (ושדות המידע) של w. כעת יש לv לכל היותר בן אחד. המשך בצעד 1 או 2 כנדרש..1.2.3.4.5 זמנים זמן חיפוש/הכנסה/הוצאה הוא ליניארי בגובה העץ. במקרה שיש בידינו עץ שלם, גובה העץ הוא. log n במקרה שהעץ נראה כמו רשימה ליניארית, 1 n. =h ניתן להוכיח כי הגובה הממוצע של עץ בינארי הוא.O(log n) סיור Inorder ועץ חיפוש בינארי קבלת סדרה ממוינת של המפתחות בעץ: אם נתון לנו עץ חיפוש בינארי, נוכל לקבל סדרה ממוינת של המפתחות בעץ בזמן,O(n) וזאת על ידי סריקת העץ ב- inorder. במהלך הסריקה, כאשר אנו בודקים את ערך הצומת, אנו מדפיסים אותו. מימוש פעולת המילון "עוקב": על מנת לממש על עץ חיפוש בינארי את הפעולה "עוקב" המוגדרת עבור מילון, כל שעלינו לעשות הוא למצוא את האיבר שנמצא אחרי הצומת המבוקש ב- inorder. זאת על פי הטענה שאנו מקבלים את האיברים בסדר ממוין כאשר אנו מבצעים סריקת.inorder עמוד 46

.7.5 עץ AVL הגדרה משפחה של עצים תקרא מאוזנת אם (n ht ( ) = O(log הגדרה. עץ AVL הוא עץ חיפוש בינארי, שבו לכל צומת v התכונה: 1 right) h(v left) h(v עצי פיבונצי נגדיר כעת משפחה נוספת של עצים. משפחה זו משמשת בהוכחת חסם הגובה על עצי.AVL עצי פיבונצי מוגדרים בצורה הבאה: F0 F1 F2 F3 טענה 1.h גובה F h לכל h, לעץ טענה 2. F = 1+ F + F F h h 1 h 2 h 1 מתקיים: עמוד 47

טענה 3. T F h יהי T עץ AVL בעל גובה h, אזי הערה: ניתן לראות לפי הגדרה כי עצי פיבונצי הם עצי.AVL טענה זו אומרת כי עצי פיבונצי הם עצי ה- AVL הגדלים לגובה במהירות הגדולה ביותר מבין כל עצי ה- AVL ומכאן המוטיבציה להוכיח טענה על עצי AVL בעזרתם. טענה 4 n i F = n + i i 3 1 F i לעץ פיבונצי יש צמתים, כאשר הוא המספר הפיבונצי ה- i. טענה 5. h= יהי T עץ AVL בן n צמתים, אזי (n O(log איזון בעץ AVL זמן החיפוש בעץ AVL הוא הנותר יהיה עץ.AVL (n.o(log נצטרך לדאוג שאחרי הכנסה או הוצאה של איברים מהעץ, העץ תיקון העץ לאחר הכנסה או הוצאה של איבר, כך שבסוף יתקבל שוב עץ,AVL נקרא גלגול. עבור צומת v בעץ בינארי נסמן: h () L v h () R v הוא גובה תת העץ הימני של v. הוא גובה תת העץ השמאלי של v.. BF() v = h() v h() v L R גורם האיזון Factor) (Balance מוגדר כהפרש הגבהים: עמוד 48

.1.2.3 אבחנות: הצמתים היחידים שאולי הופר בהם האיזון הם הצמתים לאורך מסלול הכנסה/הוצאה. אם עבור צומת v במסלול הנ"ל גובה העץ ששורשו v לא השתנה, אזי גורמי האיזון בצמתים שמעליו במסלול לא השתנו. אם גורם האיזון הופך ל- 2 או ל -2, אזי יש לבצע גלגול על מנת שהעץ יחזור להיות עץ.AVL.4 גלגול - פעולה המתבצעת על צומת שהופר בו האיזון על מנת להחזירו לתחום המותר.[ 1, 0,1].5 גורם האיזון לא יכול להיות גדול מ- 2 בערכו המוחלט, כי בכל הכנסה או הוצאה הוא משתנה ב- 1 לכל היותר. אלגוריתם לתיקון גורמי האיזון לאחר הכנסה/הוצאה מכל צומת v לאורך המסלול החל מלמטה ועד השורש בצע: עדכן את.BF(v) אם גובה תת העץ אשר v שורשו לא השתנה, סיים. אם אם גובה תת העץ השתנה ו-( BF(v תקין, המשך כלפי מעלה. BF(v) = 2 - בצע גלגול והמשך כלפי מעלה. סוגי הגלגולים הדרך לתקן חוסר איזון בצומת, תלוי בצורה בה האיזון מופר. ניתן לסווג חוזר איזון בארבע קטגוריות שונות המכסות את כל המקרים. הגלגול המתאים בבן הימני v בבן השמאלי v בשורש v BF(v)=2 BF(v)=2 L L R BF(v ) 0 LL BF(v ) = 1 LR L BF(v)=-2 BF(v R ) 0 RR BF(v)=-2 BF(v R ) = 1 RL עמוד 49

גלגול LL לפני הכנסת v, גובה העץ הוא 2+h. הוכנס צומת v A L שהגדיל את גובל לשורש. לh+1. גלגול LL יעביר את A +1 B +2 0 A +1 B R AL h AR v גובה העץ לאחר הגלגול הוא 2+h, כמו לפני ההכנסה. A 0 השורש מאוזן. (1)O. מצביעים ולכן זמן הגלגול הוא (1)O שינינו h B 0 A L v A R B R גלגול LR B L הוכנס איבר ל שגרם לו להעלות את +1 C +2 גובהו ל- h. 0 A -1 h 0 B +1 C R A L BL h-1 BR v B גובה העץ אחרי הגלגול הוא 2+h, כמו לפני ההכנסה. 0 A -1 C שינינו (1)O מצביעים ולכן זמן הגלגול הוא.O(1) A L h BL h-1 B R CR h v באופן סימטרי, אנו מבצעים את שני סוגי הגלגולים האחרים. עמוד 50

.7.6 עצי 3-2 תזכורת משפחת עצים נקראת מאוזנת אם n). H ( T) = O(log עצי AVL הם עצים מאוזנים. עצי 2-3 הם דוגמא נוספת לעצים מאוזנים. הגדרה עץ 2-3 הוא עץ בו כל העלים נמצאים באותה רמה ולכל צומת פנימי 2 או 3 בנים. דוגמאות גובה עצי 2-3 מספר העלים K בעץ 2-3 מקיים h 3 L 2, כאשר h הוא גובה העץ. החסם התחתון מתקבל כאשר אנו מביטים בעץ הבינארי השלם הנוצר על ידי סילוק כל ילד שלישי מעץ 2-3. החסם העליון מתקבל כאשר אנו מביטים בעץ הטרינארי הנוצר על ידי הוספת ילד שלישי לעץ 2-3 בכל מקום בו חסר ילד. גובה העץ מקיים:. h=θ ( log L) כלומר:, log h L h log L 3 2 עמוד 51

עצי 2-3 כמבני נתונים כל עלה מכיל מפתח ורשומה. 2 בנים, ויש לו 1 d אינדקסים המשתמשים לחיפוש הרשומה הנחוצה. לכל צומת פנימי יש 3 d בצומת פנימי בעל שני בנים רשום אינדקס בודד הגדול ממש מהמפתח המקסימאלי בתת העץ ששורשו הוא הבן הראשון וכן קטן או שווה למפתח המינימאלי בתת בעץ ששורשו הוא הבן השני. בצומת פנימי בעל שלושה בנים רשומים שני אינדקסים. האינדקס הראשון גדול ממש מהמפתחות בעץ הראשון וקטן שווה מהמפתחות בעץ השני. האינדקס השני גדול ממש מהמפתחות בעץ השני וקטן או שווה מהמפתחות בעץ השלישי. חיפוש מפתח k בעץ 2-3 יהי v השורש של העץ. אם v עלה, בדוק אם k נמצא בצומת v. k 1 יהי האינדקס המינימאלי בצומת v. k < k 1 אם המשך את החיפוש בבן הראשון של v. אחרת, אם לv רק שני בנים או ש- k קטן מהמפתח השני של v, המשך את החיפוש בבן השני של v. אחרת, המשך את החיפוש בבן השלישי של v. הוספת מפתח k לעץ 2-3 חפש את k בעץ T. אם k נמצא, סיים. אם k אינו ב- T, יהי f הצומת האחרון, שאינו עלה, במסלול החיפוש. צור עלה חדש בעל המפתח k והוסף אותו כבן ל- f, תוך שמירת הסדר בין הבנים של f (יתכן כעת כי ל- f ארבעה בנים). הוסף ל- f אינדקס נוסף בהתאם לכללי עץ 2-3. v f אם ל- v ארבעה בנים, פצל את v לשני צמתים,v1, וחבר אותם כבנים לאב f של הצומת v2 v, תוך שמירה על סדר האינדקסים הנכון. חזור לצעד 5. אם v הוא שורש צור צומת f אשר בניו הם הצמתים,v1 וסיים. אם ל- v שלושה בנים סיים. v2.1.2.3.4.5.6 עמוד 52

המחשה פיצול צומת בעץ 2-3 בעלת ארבעה בנים לשני צמתים: k 2 kkk 1 2 3 v v v v 1 2 3 4 k 1 v v 1 2 k 3 v v 3 4 תכונות תהליך ההוספה שינויים מתבצעים רק על המסלול מהשורש לעלה שהוסף. בזמן פיצול של צומת, הצמתים החדשים הם בעומק שווה לצומת שפוצל. בפיצול השורש נוצר צומת חדש שמגדיל ב- 1 את העומק של כל הצמתים. מסקנה לאחר הוספה של עלה, כל העלים באותו עומק ולכל צומת פנימי 2-3 בנים. אלגוריתם להוצאת מפתח k מעץ 2-3 חפש את k בעץ. אם k לא נמצא בעץ, סיים. יהי l העלה שערכו k ויהי f אביו. סלק את l מהעץ. v f אם v הוא שורש ולו בן בודד, סלק את v וסיים. אם ל- v נותרו שני בנים, סיים (המשך אם ל- v נותר רק בן בודד). מקרה א': אם ל- v יש אח ולו שלושה בנים, שאל בן מהאח (תקן את ערכי ההורים) וסיים. מקרה ב': אם לכל אח רק שני בנים, אחד עם v עם אח קרוב לv, ועדכן את המפתחות בצומת שנוצר. יהי f ההורה של v. חזור לצעד 4..1.2.3.4.5.6.7.8 עמוד 53

תרגיל יהי T עץ 3-2 ויהי T העץ המתקבל מהוספת הצומת x ל- T והוצאתו. נניח כי בהוצאת x לא היה צורך לבצע איחודים. האם? T = T תשובה לא בהכרח. הרעיון: יתכן כי ביצענו פיצול בהכנסה, אולם בהוצאה, במקום לבצע איחוד, ביצענו הלוואה מאח. דוגמא: 20 7, 10 30, 40 5 7 10 20 30 40 נוסיף 8: 8, 20 7 10 30, 40 5 7 8 10 20 30 40 עמוד 54

נמחק את 8, ונבצע הלוואה מאח: 10, 30 7 10 40 5 7 10 20 30 40 עמוד 55

.7.7 עצי B+ הגדרה.1.2 עץ +B מדרגה m הוא עץ המקיים את התכונות הבאות: כל הערכים נמצאים בעלים, כל העלים באותה רמה. לכל צומת פנימי, פרט אולי לשורש, יש c בנים כאשר מספר הבנים הוא m/2. לשורש c m. 2 c m.3 לצומת פנימי בעל c בנים יש 1-c אינדקסים ממוינים לפי גודלם. כל המפתחות הנמצאים בתת העץ ה- i קטנים מהאינדקס ה- i וגדולים או שווים לאינדקס ה- i-1. כל המפתחות הנמצאים בתת העץ הימני ביותר גדולים או שווים לאינדקס האחרון. פעולות פעולות החיפוש, ההכנסה וההוצאה נעשים כמו בעץ 2-3. פעולת הכנסה:.1.2.3.4 נמצא מקום להכנסת האיבר החדש ברמה התחתונה. נוסיף את האיבר לעץ יחד עם המפתח המתאים לאביו. אם דרגת צומת האב תקינה, נסיים. אחרת (הדרגה היא 1+m), נפצל את צומת האב לשני צמתים, כך שהשמאלי מביניהם m + 1 הצמתים הראשונים, והימני את יקבל את 2 את המפתח k m + 1 2.5 m + 1 האחרונים. 2 נכניס לאביו של הצומת המפוצל כדי להפריד בין הבנים החדשים. נמשיך באופן רקורסיבי כלפי מעלה. אם פיצלנו את שורש העץ, נוסיף שורש חדש. עמוד 56

פעולת הוצאה: 1. נמצא את האיבר שרוצים להוציא ברמה התחתונה. 2. נמחק את האיבר, ביחד עם המפתח המתאים מאביו. 3. אם דרגת צומת האב תקינה, נסיים. ( קיימים שני מקרים: m אחרת (הדרגה היא 1 2 m בנים, נלווה בן ימני ביותר אם לאח השמאלי (או הימני) של צומת האב יש יותר מ- 2 (שמאלי ביותר) מהאח ונסיים). אחרת (לאח יש m בנים בדיוק) נאחד את הצומת עם אחיו ונמשיך באופן רקורסיבי כלפי 2 מעלה. אם נגיע למצב שלשורש נותר בן יחיד, נבטל את השורש. עמוד 57

7.8. מידע נוסף בעצי חיפוש בשימושים רבים של עצי חיפוש, נרצה לשמור אינפורמציה נוספת בכל צומת, מלבד הנתונים המאוחסנים בה. על ידי הוספת אינפורמציה, נוכל להשיג האצה של פעולות נוספות הנדרשות מעצי חיפוש. נביט כעת מספר דוגמאות למידע נוסף שאפשר לשמור בעץ ובשימושים שנעשה במידע זה. עץ דרגות Tree) (Rank הגדרה האינדקס (rank) של מספר x בקבוצה S הוא מקומו בסדרה ממוינת של איברי S. מטרה נרצה לממש עץ חיפוש התומך במציאת האינדקס של איבר x. הגדרה עץ דרגות Tree) (Rank הוא עץ בו בכל צומת v נשמרים מספר הצמתים בתת העץ ששורשו v. טענה בעזרת עץ דרגות, ניתן לממש עץ חיפוש התומך בפעולה "מציאת האינדקס של איבר x" בזמן.O(height) מימוש: נחפש את האיבר x. נספור את הצמתים על מסלול החיפוש ל- x הקטנים מ- x, בתוספת הערכים השמורים בבניהם השמאליים. כאשר נגיע אל x יהיה בידינו האינדקס שלו. מסקנה בעץ דרגות מציאת ה- rank דורשת זמן.O(height) עמוד 58

דוגמא נרצה לממש עץ חיפוש התומך במציאת סכום האיברים בעץ הקטנים מ- x בזמן.O(height) פתרון נשמור בכל צומת v את סכום ערכי הצמתים בתת העץ ששורשו v. נסמן מספר זה ב-( S(v. נסכם את הערכים על מסלול החיפוש ל- x הקטנים מ- x בתוספת הערכים השמורים בבניהם השמאליים. זמן הריצה של פתרון זה הוא.O(height) עץ דרגות מאוזן נרצה לממש עץ חיפוש מאוזן התומך במציאת האינדקס (rank) של איבר x בזמן.O(log(n)) על מנת לעשות זאת, נוכל להשתמש באחד מסוגי העצים המאוזנים שראינו קודם, למשל, עץ.AVL בזמן ביצוע הגלגולים של עץ ה- AVL, נזכור שיש לעדכן גם את השדה הנוסף בכל צומת. השוואה בין עצי 2-3 ועצי AVL שני סוגי העצים תומכים בפעולות המילון בזמן.O(log(n)) בעץ 2-3 רשומות נשמרות רק בעלים. בעץ AVL רשומות נשמרות גם בצמתים הפנימיים וגם בעלים. בדרך כלל הבחירה בין שימוש בעצי AVL לשימוש בעצי 2-3 איננה עקרונית. (שניהם מסובכים ועושים כאב ראש למי שמתכנת אותם). עמוד 59

תרגיל נתון עץ AVL שבו כל צמת מכיל מפתח ומצביעים לשני בנים. כל מפתח מופיע בעץ פעם אחת לכל היותר. תארו אלגוריתם המממש את הפעולה הבאה: Distance (Root, LeftKey, RightKey) כאשר RightKey ו- LeftKey הם שני מפתחות המקיימים.LeftKey < RightKey אם לפחות אחד משני המפתחות אינו בעץ, השגרה מחזירה 1-. אחרת היא מחזירה את המרחק בקשתות בין שני הצמתים בעץ המאחסנים את RightKey ו-.LeftKey (כלומר את מספר הקשתות שבמסלול הקצר ביותר ביניהם). סיבוכיות הזמן הנדרשת (n O(log במקרה הגרוע ביותר, כאשר n הוא מספר המפתחות המאוחסנים בעץ. פתרון האלגוריתם Distance (Root, LeftKey, RightKey) חפש את RightKey ו- LeftKey בעץ. אם אחד מהם לא נמצא החזר 1-. p=root כל עוד לא מתקיים (LeftKey<P<RightKey) אם p>leftkey וגם p>rightkey אז p=p->leftson אם p<leftkey וגם p<rightkey אז p=p->rightson o o p1=p, h1=0 כל עוד p1!=leftkey p1=p1->leftson p1>leftkey אם o o o אם p1=p1->rightson p1<leftkey h1++ p2=p,h2=0 כל עוד p2!=rightkey p1>rightkey אם o אם o p1=p1->leftson p1=p1->rightson p1<rightkey h2++ o החזר h1+h2+1 עמוד 60

רעיון האלגוריתם אנו מוצאים את האבא המשותף של שני הצמתים המבוקשים (קיים רק אחד כזה), וממנו אנו יורדים אל כל אחד מהצמתים, תוך כדי ספירת מספר הצמתים בינו לבן האב. חיבור שני סכומים אלו נותן לנו את המרחק בין הצמתים. סיבוכיות אנו מטיילים מספר פעמים קבוע (4 פעמים) על העץ. מכיוון שהעץ הוא עץ מאוזן, גובהו חסום על ידי (n,o(log ולכן זוהי גם סיבוכיות האלגוריתם. תרגיל נתון עץ 2-3 עם ערכים בעלים: 6, 11 4, 5 7, 8 13, 15 2 4 5 6 7 8 11 13 15 insert(18), insert(1), delete(13) על העץ מופעלת סדרת הפעולות הבאה (משמאל לימין): צייר את העץ המתקבל לאחר כל פעולה. עצים) ולא את שלבי הביניים. יש לצייר רק את העצים המתקבלים בתום הפעולות (סה"כ 3 עמוד 61

פתרון insert(18) 11 6 15 4, 5 7, 8 13 18 2 4 5 6 7 8 11 13 15 18 insert(1) 11 4, 6 15 2 5 7, 8 13 18 1 2 4 5 6 7 8 11 13 15 18 delete(13) 6 4 11 2 5 7, 8 15, 18 1 2 4 5 6 7 8 11 15 18 עמוד 62

8. רשימת דילוגים 8.1. רשימת דילוגים רנדומאלית עבור עצים מאוזנים, מימוש פעולות המילון נעשה בזמן (n O(log במקרה הגרוע ביותר. מימוש הפעולות אינו טריוויאלי, במיוחד כאשר יש צורך לתמוך גם בפעולות הדורשות לשמור בכל צומת אינפורמציה ייחודית (כמו (rank ולעדכן אותה. נציג מבנה נתונים בעל מימוש פשוט יותר, שלא דורש איזונים לאחר הכנסה/הוצאה. בתמורה לכך, ביצוע פעולות המילון יעשה בזמן n) O(log בממוצע. ראינו כבר שעצי חיפוש ללא פעולות איזון יכולים לשמש למימוש פעולות המילון בזמן (n O(log בממוצע. בניתוח שעשינו הנחנו שהוכנסו n איברים לעץ, לפיכך קיימות!n פרמוטציות להכנסתם. הממוצע של גובה!n העצים שנוצרו הוא.O(log n) בניתוח זה ישנן מספר בעיות. ראשית, בדרך כלל ההסתברות להופעת פרמוטציה בקלט איננה אחידה. שנית, מבנה הנתונים שנוצר תלוי בסדר הכנסת הנתונים. אדם/תהליך המחבל במערכת יכול להכניס סדרת נתונים כך שהפעולות יבוצעו בזמן האיטי ביותר. במבנה שנציג - רשימת דילוגים, בעיות אלו נפתרות. הפעולות וזמן ביצוען תלוי בהגרלות שעושה המחשבים, ולא בסדר הכנסת הנתונים. הממוצע מחושב לפי ההגרלות ולא לפי הנחות על ההסתברות של הקלטים. אלגוריתם כזה נקרא אלגוריתם רנדומאלי. נביט ברעיון של מבנה הנתונים. ניקח רשימה ממוינת של איברים. חיפוש איבר בסוף הרשימה הוא יקר (מבחינת פעולות). 2 11 12 15 21 24 25 26 36 65 כדי לזרז את החיפוש (פי 2), נוסיף מדריך - תת רשימה של כל איבר שני. ממדריך זה יהיה אפשר להגיע לאיבר המתאים ברשימה הראשונה. 2 12 21 25 36 2 11 12 15 21 24 25 26 36 65 עמוד 63

כדי לזרז את החיפוש במדריך נוסיף רמה נוספת: 2 21 36 2 12 21 25 36 2 11 12 15 21 24 25 26 36 65 כך נמשיך עד לרמה n log בה יהיה איבר בודד. כדי לפשט את האלגוריתמים המממשים רשימת דילוגים, נהוג להוסיף צומת דמה בתחילת כל שורה ברשימת הדילוגים, וכן צומת אחת בסוף רשימת הדילוגים, שכל השורות יסתיימו בה. 2 21 36 2 12 21 25 36 2 11 12 15 21 24 25 26 36 65 אורך מסלול החיפוש הוא במהלך החיפוש, במעבר מרמה לרמה אנו עוברים על פני שני מצביעים לכל היותר. לפיכך, אורך המסלול. 2logn מספר הצמתים הכולל אינו עולה על. 2n פעולת חיפוש ברשימת דילוגים (id) p מקבל את כתובתו של הצומת העליון השמאלי ביותר. כל עוד לא הגעת אל תחתית רשימת הדילוגים או לא הגעת אל סופה, בצע: כל עוד p.right.id id בצע: אם לא הגעת אל תחתית הרשימה, בצע. p p.right. p p.down אם p.id = id החזר את p. אחרת החזר: "האיבר המבוקש איננו ברשימת הדילוגים"..1.2.3.4.5 עמוד 64

פעולת ההכנסה ברשימת דילוגים חפש את k. אם k נמצא, סיים. שמור מצביע לצומת הימני ביותר בכל רמה במסלול החיפוש. הוסף צומת חדש ברמה התחתונה ביותר וקבע את המפתח להיות k. לפי סדר הרמות מלמטה למעלה: הגרל מטבע.toss() אם יוצא 0: הוסף צומת חדש מעל הרמה הנוכחית וקבע את המפתח בו להיות k. אם יוצא 1: עצור. אם ברמה העליונה הוגרל 0, הוסף רמה חדשה..1.2.3.4.5 פעולת הוצאה מרשימת דילוגים מצא את האיבר בעל המפתח k. הוצא איבר זה מכל הרמות בהן הוא מופיע..1.2 מספר הצמתים ברשימת דילוגים מספר הצמתים הממוצע ברשימת דילוגים הוא 2n, כאשר n הוא מספר המפתחות במבנה. אורך מסלול החיפוש הממוצע. L 2log n+ 2 2 האורך הממוצע L של מסלול חיפוש ברשימת דילוגים עם n מפתחות מקיים זמן ביצוע הפעולות חיפוש, הכנסה, והוצאה מרשימת דילוגים נעשים בזמן ממוצע (n O(log כיוון שבכל צעד על מסלול החיפוש מתבצעים (1)O צעדים. עמוד 65

י- underwar@hotmail.com 8.2. רשימת דילוגים דטרמיניסטית כאשר אנו משתמשים ברשימת הדילוגים הרנדומאלית, הפעולות וזמן ביצוען תלוי בהגרלות שעושה המחשבים, ולא בסדר הכנסת הנתונים. בממוצע אנו מקבלים זמני ביצוע פעולות של.O(log n) אולם, רשימת הדילוגים הרנדומאלית מתבססת על כך שמנוע יצירת המספרים האקראיים של המחשב מתנהג "כמצופה". במידה והמצב הוא לא כזה, עשויה רשימת הדילוגים להראות כרשימה מקושרת פשוטה, וסיבוכיות הפעולות עליה יהיו ליניאריות במקרה הגרוע בהתאם. נרצה למצוא דרך להשתמש ברשימת דילוגים, בעזרתה נוכל להגיע לזמני ביצוע פעולות של במקרה הגרוע. כידוע - קיימים מבני נתונים, עצי חיפוש, המאפשרים לממש מילון ב- O(log n) - עצי,AVL עצי,2-3 O(log n) עצי red-black ועוד. אנו מחפשים אלטרנטיבה למבנים אלו עקב המימוש המסובך שלהם. נציג פתרון המשתמש ברשימת דילוגים בהדרגתיות, תוך כדי הצגת הדרך כיצד פותח הפיתרון הסופי בו נשתמש. נקודת ההתחלה הגדרה רשימת דילוגים L תכונה רשימת דילוגים מאוזנת בשלמות אם היא מקיימת את התנאים הבאים: 1. L היא רשימת דילוגים. 2. עבור k טבעי קבוע כלשהו, מתקיים כי כל איבר k -י בגובה h ברשימת הדילוגים מופיע גם בגובה 1+h ברשימת הדילוגים. עבור רשימת דילוגים מאוזנת בשלמות, פעולת חיפוש מתבצעת בזמן לוגריתמי. אם זאת, איננו יכולים לבצע פעולות הכנסה או הוצאה על הרשימה, מבלי לפגוע בהיותה רשימת דילוגים מאוזנת בשלמות. לפיכך, נחליש מעט את הדרישה השנייה, על ידי שינוי הביטוי "עבור כל איבר ". k עמוד 66